#pragma once

#include <string>
#include <memory>
#include <functional>
#include <unistd.h>
#include "InetAddr.hpp"

class Connection;
class Reactor;
using func_t = std::function<void(Connection *)>;

class Connection
{
public:
    Connection(int sock)
        : _sock(sock),
          _R(nullptr)
    {
    }
    int Sockfd()
    {
        return _sock;
    }
    void SetEvent(uint32_t events)
    {
        _events = events;
    }
    void SetSelf(Reactor *R)
    {
        _R = R;
    }
    void Register(func_t recver, func_t sender, func_t excepter)
    {
        _recver = recver;
        _sender = sender;
        _excepter = excepter;
    }
    void Close()
    {
        if (_sock >= 0)
            ::close(_sock);
    }
    uint32_t Event()
    {
        return _events;
    }
    const func_t recver()
    {
        return _recver;
    }
    const func_t sender()
    {
        return _sender;
    }
    const func_t excepter()
    {
        return _excepter;
    }
    void AppendInbuffer(const std::string &buf)
    {
        _inbuffer += buf;
    }
    void AppendOutbuffer(const std::string &buf)
    {
        _outbuffer += buf;
    }
    void OutbufferRemove(int n)
    {
        _outbuffer.erase(0, n);
    }
    void InbufferClear()
    {
        _inbuffer.clear();
    }
    std::string &Inbuffer()
    {
        return _inbuffer;
    }
    std::string &Outbuffer()
    {
        return _outbuffer;
    }
    Reactor *Self()
    {
        return _R;
    }
    ~Connection() {}

private:
    int _sock;
    uint32_t _events;
    InetAddr _addr;
    std::string _inbuffer;
    std::string _outbuffer;
    Reactor *_R;

    func_t _recver;
    func_t _sender;
    func_t _excepter;
};